package com.jrtc.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jrtc.base.config.constants.PublicConstants;
import com.jrtc.base.entity.bo.Doctor;
import com.jrtc.base.entity.bo.Patient;
import com.jrtc.base.entity.bo.PatientAppointment;
import com.jrtc.base.entity.bo.ReservationItem;
import com.jrtc.base.entity.vo.PatientAppointmentVo;
import com.jrtc.base.entity.vo.ReserveVo;
import com.jrtc.base.util.DateUtil;
import com.jrtc.dao.DoctorDao;
import com.jrtc.dao.PatientAppointmentDao;
import com.jrtc.dao.PatientDao;
import com.jrtc.dao.ReservationItemDao;
import com.jrtc.service.PatientAppointmentService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 患者预约单表(PatientAppointment)表服务实现类
 *
 * @author makejava
 * @since 2022-03-21 17:34:12
 */
@Service("patientAppointmentService")
public class PatientAppointmentServiceImpl implements PatientAppointmentService
{
    @Resource
    private PatientAppointmentDao patientAppointmentDao;

    @Resource
    private PatientDao patientDao;

    @Resource
    private DoctorDao doctorDao;

    @Resource
    private ReservationItemDao reservationItemDao;

    /**
     * 通过ID查询单条数据
     *
     * @param appointmentId 主键
     * @return 实例对象
     */
    @Override
    public PatientAppointment queryById(Integer appointmentId) {
        return this.patientAppointmentDao.queryById(appointmentId);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<PatientAppointment> queryAllByLimit(int offset, int limit) {
        return this.patientAppointmentDao.queryAllByLimit(offset, limit);
    }

    @Override
    public IPage<PatientAppointment> queryPatientAppointmentList(PatientAppointment patientAppointment)
    {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<PatientAppointment> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(patientAppointment.getPageNo(), patientAppointment.getPageSize());
        IPage<PatientAppointment> patientAppointmentPage = this.patientAppointmentDao.queryPatientAppointmentList(page, patientAppointment);
        return patientAppointmentPage;
    }
    /**
     * 新增数据
     *
     * @param patientAppointment 实例对象
     * @return 实例对象
     */
    @Override
    public PatientAppointment insert(PatientAppointment patientAppointment) {
        this.patientAppointmentDao.insert(patientAppointment);
        return patientAppointment;
    }

    /**
     * 修改数据
     *
     * @param patientAppointment 实例对象
     * @return 实例对象
     */
    @Override
    public PatientAppointment update(PatientAppointment patientAppointment) {
        this.patientAppointmentDao.update(patientAppointment);
        return this.queryById(patientAppointment.getAppointmentId());
    }

    /**
     * 通过主键删除数据
     *
     * @param appointmentId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer appointmentId) {
        return this.patientAppointmentDao.deleteById(appointmentId) > 0;
    }

    /**
     * 患者预约列表
     * */
    @Override
    public List<PatientAppointmentVo> selectPatientAppointmentList(String appointmentTime, String type, Integer patientId) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        DateUtil dateUtil = new DateUtil();
        if (appointmentTime != null && !appointmentTime.equals("") && type != null && !type.equals("") && patientId != null && patientId != 0){
            List<PatientAppointmentVo> patientAppointmentVoList = new ArrayList<>();
            List<Date> dateList;

            Date parse;
            try {
                parse = format.parse(appointmentTime);
            } catch (Exception e){
                throw new Exception("日期转换错误");
            }

            if (type.equals(PublicConstants.Time.MOON.getValue())){//月历
                //获取包含指定日期的整个月的日期集合
                dateList = dateUtil.getAllTheDateOftheMonth(parse);

                //获取这个月包含第一天与包含最后一天的两周的日期数据集合与整个月的日期集合进行合并去重排序，得到最终的日期集合
                List<Date> forwardDate = dateUtil.dateToweek(dateList.get(0));
                List<Date> backDate = dateUtil.dateToweek(dateList.get(dateList.size() - 1));
                dateList.addAll(forwardDate);
                dateList.addAll(backDate);
                Set set = new HashSet(dateList);
                List tempList = new ArrayList(set);
                Collections.sort(tempList);
                dateList = tempList;
            }
            else if (type.equals(PublicConstants.Time.WEEK.getValue())){//周历
                dateList = dateUtil.dateToweek(parse);
            }
            else {
                throw new Exception("类型枚举出错了");
            }

            for (Date date : dateList) {
                try {
                    appointmentTime = format.format(date);
                } catch (Exception e){
                    throw new Exception("时间转换错误");
                }

                List<PatientAppointment> patientAppointments = patientAppointmentDao.selectPatientAppointmentList(appointmentTime, patientId);
                if (patientAppointments != null && patientAppointments.size() > 0){
                    for (PatientAppointment patientAppointment : patientAppointments){
                        PatientAppointmentVo patientAppointmentVo = new PatientAppointmentVo();
                        patientAppointmentVo.setAppointmentId(patientAppointment.getAppointmentId());
                        patientAppointmentVo.setPatientId(patientAppointment.getPatientId());
                        patientAppointmentVo.setDoctorId(patientAppointment.getDoctorId());
                        patientAppointmentVo.setDoctorName(patientAppointment.getDoctorName());
                        patientAppointmentVo.setAppointmentTime(patientAppointment.getAppointmentTime());
                        patientAppointmentVo.setStartTime(patientAppointment.getStartTime());
                        patientAppointmentVo.setEndTime(patientAppointment.getEndTime());
                        patientAppointmentVoList.add(patientAppointmentVo);
                    }
                }
            }

            List tempList;
            if (patientAppointmentVoList != null && patientAppointmentVoList.size() > 0){
                Set set = new HashSet(patientAppointmentVoList);
                tempList = new ArrayList(set);
            }
            else {
                tempList = patientAppointmentVoList;
            }

            return tempList;
        }
        else {
            throw new Exception("缺少必要参数");
        }
    }

    /**
     * 患者创建新预约
     * */
    @Override
    public int insertPatientAppointment(ReserveVo reserveVo, Integer patientId) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
        if (reserveVo != null && patientId != null && patientId != 0){
            Patient patient = patientDao.queryById(patientId);
            if (patient != null){
                PatientAppointment patientAppointment = new PatientAppointment();
                patientAppointment.setPatientId(patientId);
                patientAppointment.setPatientName(patient.getPatientName());
                patientAppointment.setPatientAge(patient.getAge());
                patientAppointment.setPatientPhone(patient.getPhone());
                patientAppointment.setPatientRegistertime(patient.getRegisterTime());
                if (reserveVo.getDesignatedDoctor() != null && !reserveVo.getDesignatedDoctor().equals("")){
                    Doctor doctor = doctorDao.selectDoctorByDoctorName(reserveVo.getDesignatedDoctor());
                    if (doctor != null){
                        patientAppointment.setDoctorId(doctor.getDoctorId());
                        patientAppointment.setDoctorName(doctor.getDoctorName());
                    }
                    else {
                        throw new Exception("未查到医生信息");
                    }
                }
                patientAppointment.setCheckStatus(PublicConstants.Checkstatus.NotChecked.getValue());

                String appointment;
                String startingTime;
                try {
                    appointment = format.format(reserveVo.getAppointment());
                    startingTime = dateFormat.format(reserveVo.getAppointment());
                } catch (Exception e){
                    throw new Exception("时间转换错误");
                }

                patientAppointment.setAppointmentTime(appointment);
                patientAppointment.setStartTime(startingTime);

                long time = 30*60*1000;//30分钟
                Date afterDate = new Date(dateFormat.parse(startingTime).getTime() + time);
                patientAppointment.setEndTime(format.format(afterDate));

                ReservationItem reservationItem = reservationItemDao.selectReservationItemByReservationItemName(reserveVo.getReservationItem());
                if (reservationItem != null){
                    patientAppointment.setReservationItemId(reservationItem.getReservationItemId());
                }
                else {
                    throw new Exception("未查到预约项目");
                }
                int i = patientAppointmentDao.insertPatientAppointment(patientAppointment);
                if (i > 0){
                    return i;
                }
                else {
                    throw new Exception("创建新预约失败");
                }
            }
            else {
                throw new Exception("未查到患者信息");
            }
        }
        else {
            throw new Exception("缺少必要参数");
        }
    }
}